package org.cloud.feign.utils;


import brave.ScopedSpan;
import brave.Tracer;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import feign.Feign;
import feign.FeignException;
import feign.FeignException.ServiceUnavailable;
import feign.RetryableException;
import lombok.extern.slf4j.Slf4j;
import org.cloud.entity.LoginUserDetails;
import org.cloud.feign.service.ICommonServiceFeignClient;
import org.cloud.feign.service.ICommonServiceMessageLogFeign;
import org.cloud.feign.service.IGatewayFeignClient;
import org.cloud.feign.service.IParamConfigFeignClient;
import org.cloud.utils.SpringContextUtil;
import org.cloud.vo.ParamConfigVO;
import org.springframework.cloud.openfeign.FeignClientBuilder;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.web.client.HttpClientErrorException;

@Slf4j
public final class FeignUtil {



    public LoginUserDetails getLoginUser() {
        try {
            return gatewayFeignClient.getAuthentication();
        } catch (HttpClientErrorException.Unauthorized e) {
            log.info("rest请求无权限");
        } catch (ServiceUnavailable | RetryableException serviceUnavailable) {
            log.warn("网关服务未启动，请稍后!");
        } catch (FeignException.Unauthorized e) {
            log.debug("feign请求,未带用户信息!");
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode().value() != HttpStatus.UNAUTHORIZED.value()) {
                log.error(e.getMessage(), e);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 根据token获取用户信息
     *
     * @param token
     * @return
     */
    public LoginUserDetails getLoginUser(String token) {
        try {
            return gatewayFeignClient.getAuthentication(token);
        } catch (ServiceUnavailable | RetryableException serviceUnavailable) {
            log.warn("网关服务未启动，请稍后!");
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode().value() != HttpStatus.UNAUTHORIZED.value()) {
                log.error(e.getMessage(), e);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public ParamConfigVO getParamConfig(String code) {
        ParamConfigVO paramConfigVO = paramConfigFeignClient.get(code);
        if (paramConfigVO == null) {
            return ParamConfigVO.builder().configCode(code).build();
        }
        return paramConfigVO;
    }

    public Boolean update(ParamConfigVO paramConfigVO) {
        return paramConfigFeignClient.update(paramConfigVO);
    }

    public int sendTelMsg(final String chatId, final String message, String parseMode) {
        ThreadUtil.execAsync(() -> {
            ScopedSpan span = tracer.startScopedSpan(IdUtil.fastSimpleUUID());
            try {
                return commonServiceFeignClient.sendTelMsg(chatId, message, parseMode);
            }finally {
                span.finish();
            }
        });
        return 1;
    }
    /**
     * 发送markdown格式的telgram消息 http://core.telegram.org/bots/api#markdownv2-style
     *
     * @param chatId
     * @param message
     * @return
     */
    public int sendTelMsgMarkdownV2(final String chatId, final String message) {
        return this.sendTelMsg(chatId, message, "MarkdownV2");
    }

    public <T> T getFeignClient(String serviceName, Class<T> clazz) {
        return this.feignClientBuilder.forType(clazz, serviceName).build();
//        Feign.Builder builder = feignContext.getInstance(serviceName, Feign.Builder.class);
//        if (builder == null) {
//            throw new IllegalArgumentException("Service not found: " + serviceName);
//        }
//        return builder.target(clazz, "http://" + serviceName);
    }

    public final IGatewayFeignClient gatewayFeignClient;
    public final IParamConfigFeignClient paramConfigFeignClient;
    public final ICommonServiceFeignClient commonServiceFeignClient;
    public final ICommonServiceMessageLogFeign messageLogFeignClient;
//    private final FeignContext feignContext;
    private final FeignClientBuilder feignClientBuilder;
    private final Tracer tracer;
    @Lazy
    private FeignUtil() {
        gatewayFeignClient = SpringContextUtil.getBean(IGatewayFeignClient.class);
        paramConfigFeignClient = SpringContextUtil.getBean(IParamConfigFeignClient.class);
        commonServiceFeignClient = SpringContextUtil.getBean(ICommonServiceFeignClient.class);
        messageLogFeignClient = SpringContextUtil.getBean(ICommonServiceMessageLogFeign.class);
        feignClientBuilder = new FeignClientBuilder(SpringContextUtil.getApplicationContext());
        tracer = SpringContextUtil.getBean(Tracer.class);
    }


    private static class Handler {

        private Handler() {
        }

        private static final FeignUtil handler = new FeignUtil();
    }

    public static FeignUtil single() {
        return Handler.handler;
    }


}
